package cogbio.polFileGenerator;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;



public class PolFileGenerator {
	
	private static MainGui parent = null;

	private static String aPath = null;
	private static String bPath = null;
	private static int genAmount = 0;
	
	private static int genFileOffset = 0;
	private static String cPath = null;
	/**
	 * @param multiple 
	 * @param args
	 */
	public static void generate(String fileName, String headerText, String posMask, String negMask, int sessionSize, int limit, boolean firstPositive, int multiple ){

		if (fileName == null){
			fileName = "PolFile.txt";
		}
		
		List<String> positives = new ArrayList<String>();
		List<String> negatives = new ArrayList<String>();
		List<String> aClass = null;
		List<String> bClass = null;

		List<String> cClass = null;
		
		File[] listOfAClass = null;
		File[] listOfBClass = null;

		File[] listOfCClass = null;
		
		File positiveFolder = new File(posMask);
		File[] listOfPositives = positiveFolder.listFiles();
		System.out.println("Amount of positives = "+listOfPositives.length);

		File negativeFolder = new File(negMask);
		File[] listOfNegatives = negativeFolder.listFiles();
		System.out.println("Amount of negatives = "+listOfNegatives.length);

		if((listOfPositives.length+listOfNegatives.length)<sessionSize){
			sessionSize = listOfPositives.length+listOfNegatives.length;
			PolFileGenerator.parent.showMessage("Training folders do not contain enough images to fill the session. Setting sessionSize to "+sessionSize+".");
		}
		if (genAmount>0){
			
			if(bPath==null || bPath.length()==0){
				cPath=aPath;
			}

			aClass = new ArrayList<String>();
			bClass = new ArrayList<String>();
		
			if (!(aPath==null || aPath.length()==0)&& !(bPath==null|| bPath.length()==0)) {
				
				File aFolder = new File(aPath);
				File bFolder = new File(bPath);
				
				listOfAClass = aFolder.listFiles();
				listOfBClass = bFolder.listFiles();
				
				//Utils.shuffle(listOfAClass);
				//Utils.shuffle(listOfBClass);
				
				for (File current: listOfAClass){
					aClass.add(current.getAbsolutePath());
				}
				for (File current: listOfBClass){
					bClass.add(current.getAbsolutePath());
				}
				System.out.println("Class A size: "+aClass.size());
				System.out.println("Class B size: "+bClass.size());
			}
			
			if (!(cPath==null|| cPath.length()==0)){
				System.out.println("Lonely cPath:"+cPath);
				cClass = new ArrayList<String>();

				File cFolder = new File(cPath);
				listOfCClass = cFolder.listFiles();
				int i=0;
				for (File current: listOfCClass){
					cClass.add(current.getAbsolutePath());
					if (i++%2==0){
						aClass.add(current.getAbsolutePath());
					} else {
						bClass.add(current.getAbsolutePath());
					}
				}
				aClass = Utils.shuffle(aClass);
				bClass = Utils.shuffle(bClass);
			}
		}

		
		
		int amount = Math.min(listOfPositives.length, listOfNegatives.length);
		
		
		Utils.shuffle(listOfNegatives);
		Utils.shuffle(listOfPositives);
		
		
			
		
		
	try {
		
		Writer output = null;
		File file = new File(fileName);
		output = new BufferedWriter(new FileWriter(file));
		
		if(headerText!=null){
			String[] headerParts = headerText.split("\n");
			for (String current: headerParts){
				output.write(current);
				((BufferedWriter) output).newLine();
			}
			//((BufferedWriter) output).newLine();
		}
		output.write("[Trials]");
		((BufferedWriter) output).newLine();
		
		
		for(int l=0;l<multiple;l++){
			String[][] files = new String [2*amount/sessionSize][sessionSize];
			
			
			int k=0;
			int cluster = 0;
			
				for(File current: listOfPositives){
					positives.add(current.getAbsolutePath());
					files[cluster][k++]=current.getAbsolutePath();
					if (k%(sessionSize/2)==0){
						cluster++;
						System.out.println(cluster);
						k=0;
						if (cluster>=(2*amount/sessionSize)){
							break;
						}
						}
				}
				cluster = 0;
				for(File current: listOfNegatives){
					negatives.add(current.getAbsolutePath());
					files[cluster][k+++(sessionSize/2)]=current.getAbsolutePath();
					if (k%(sessionSize/2)==0){
						cluster++;
						//System.out.println(cluster);
						k=0;
						if (cluster>=(2*amount/sessionSize)){
							break;
						}
						}
				}
			
			
			for (int ii=0;ii<(2*amount/sessionSize);ii++){
				String[] internalFiles = files[ii];	
				
				
				Utils.shuffle(internalFiles);

				if (firstPositive){
					System.out.println("first is positive");
					Utils.getFirstPositive(internalFiles, positives, sessionSize);
				}
				
				//Shuffle.show(files);
				if(limit!=0){
					Utils.removeClusters(internalFiles, positives, negatives, limit);
				}
				//Shuffle.show(files);
				if(genAmount>0){
					System.out.println("HalfGenAmount:"+genAmount/2);
					String[] currentAClass = new String[genAmount/2];
					String[] currentBClass = new String[genAmount/2];
					int positionI = 0;
					for (String current: aClass){
						if (positionI++<genFileOffset){
							//System.out.println("Skipping "+positionI);
							continue;
						}
						//System.out.println("Writing to: "+(positionI-(ii*genAmount/2)-1));
						currentAClass[positionI-1-genFileOffset] = current;
						
						if (positionI-genFileOffset>=genAmount/2){
							break;
						}
					}
					positionI = 0;
					for (String current: bClass){
						if (positionI++<genFileOffset){
							continue;
						}
						
						currentBClass[positionI-1-genFileOffset] = current;
						
						if (positionI-genFileOffset>=genAmount/2){
							break;
						}
					}
					genFileOffset+= genAmount/2;
					System.out.println("Gen File offset:"+genFileOffset);
					Utils.pushGeneralizationFiles(internalFiles,currentAClass,currentBClass,genAmount);
				}


				for (int i = internalFiles.length-1;i>=0;i--){
					if (positives.contains(internalFiles[i])){
						output.write("[+]"+internalFiles[i]);
						((BufferedWriter) output).newLine();
					} else if (negatives.contains(internalFiles[i])){
						output.write("[-]"+internalFiles[i]);
						((BufferedWriter) output).newLine();
					} else if (cClass!=null && cClass.contains(internalFiles[i])){
						output.write("&[C]"+internalFiles[i]);
						((BufferedWriter) output).newLine();
					} else if (aClass.contains(internalFiles[i])){
						output.write("&[A]"+internalFiles[i]);
						((BufferedWriter) output).newLine();
					} else if (bClass.contains(internalFiles[i])){
						output.write("&[B]"+internalFiles[i]);
						((BufferedWriter) output).newLine();
					} 
					
				}
				//if(i%(sessionSize)==0 && i!=files.length && i!=0){
				((BufferedWriter) output).newLine();
				//}
			}
		}
		output.close();
	}catch(Exception e){
		e.printStackTrace();
	}
    System.out.println("Your file has been written");        
    
	}

	
	public static void multipleFiles(String[] names, int cycles, String header, String experimentName,String posMask, String negMask, int sessionSize, int limit, boolean firstPositive, int multiple){
		
		String suffix = "_"+experimentName;
		
		String fileName = null;
		
		for (int i=0;i<names.length;i++) {
			//System.out.println(names[i].trim());
			for (int j=0;j<cycles;j++){
				
				if (cycles==1){
					fileName= (names[i].trim()+suffix+".gngpol");
				} else {
					fileName= (names[i].trim()+suffix+"_Cycle"+(j+1)+".gngpol");
				}
					generate(fileName,header, posMask, negMask, sessionSize, limit, firstPositive, multiple);
			}
			resetGenOffset();
		}
	}


	public static void includeGenFiles(String aPath, String bPath, String cPath, int genAmount) {
		if (!(aPath==null || aPath.equals("none"))) {
			PolFileGenerator.aPath  = aPath;
			System.out.println("aPath set as "+aPath);
		}
		if (!(bPath==null || bPath.equals("none"))) {
			PolFileGenerator.bPath  = bPath;
			System.out.println("bPath set as "+bPath);
		}
		if (!(cPath==null || cPath.equals("none"))) {
			PolFileGenerator.cPath  = cPath;
			System.out.println("cPath set as "+cPath);
		}
		PolFileGenerator.genAmount = genAmount;
		
		//System.out.println(aPath+bPath+genAmount);
	}
	
	
	public static void resetGenOffset(){
		PolFileGenerator.genFileOffset = 0;
	}


	public static void setParent(MainGui mainGui) {
		PolFileGenerator.parent = mainGui;
	}
}